import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Role } from './role.entity';
import { CasbinService } from '../casbin/casbin.service';

@Injectable()
export class RoleService {
  constructor(
    @InjectRepository(Role)
    private roleRepository: Repository<Role>,
    private casbinService: CasbinService,
  ) {}

  async findAll(): Promise<Role[]> {
    return await this.roleRepository.find();
  }

  async findOne(id: number): Promise<Role | null> {
    return await this.roleRepository.findOne({ where: { id } });
  }

  async findByName(name: string): Promise<Role | null> {
    return await this.roleRepository.findOne({ where: { name } });
  }

  async create(roleData: Partial<Role>): Promise<Role> {
    const role = this.roleRepository.create(roleData);
    return await this.roleRepository.save(role);
  }

  async update(id: number, roleData: Partial<Role>): Promise<Role | null> {
    await this.roleRepository.update(id, roleData);
    return await this.roleRepository.findOne({ where: { id } });
  }

  async remove(id: number): Promise<void> {
    await this.roleRepository.delete(id);
  }

  // 获取角色的权限策略
  async getRolePolicies(roleName: string): Promise<any[]> {
    // 强制重新加载策略以确保获取最新数据
    await this.casbinService.reloadPolicy();
    const enforcer = await this.casbinService.getEnforcer();
    // 使用 g 规则查找角色的权限，而不是直接查找角色名
    const policies = await enforcer.getPolicy();
    return policies.filter(policy => policy[0] === roleName);
  }

  // 为角色分配权限
  async assignPermissionToRole(roleName: string, resource: string, action: string): Promise<boolean> {
    const enforcer = await this.casbinService.getEnforcer();
    const result = await enforcer.addPolicy(roleName, resource, action);
    if (result) {
      // 确保策略被持久化到数据库
      await this.casbinService.savePolicyToDatabase(roleName, resource, action);
      await this.casbinService.reloadPolicy();
    }
    return result;
  }

  // 为用户分配角色
  async assignRoleToUser(username: string, roleName: string): Promise<boolean> {
    const enforcer = await this.casbinService.getEnforcer();
    const result = await enforcer.addRoleForUser(username, roleName);
    if (result) {
      await this.casbinService.reloadPolicy();
    }
    return result;
  }

  // 获取用户的角色
  async getUserRoles(username: string): Promise<string[]> {
    const enforcer = await this.casbinService.getEnforcer();
    return await enforcer.getRolesForUser(username);
  }

  // 删除角色的权限
  async removePermissionFromRole(roleName: string, resource: string, action: string): Promise<boolean> {
    const enforcer = await this.casbinService.getEnforcer();
    const result = await enforcer.removePolicy(roleName, resource, action);
    if (result) {
      // 确保从数据库中删除策略
      await this.casbinService.removePolicyFromDatabase(roleName, resource, action);
      await this.casbinService.reloadPolicy();
    }
    return result;
  }

  // 删除用户的角色
  async removeRoleFromUser(username: string, roleName: string): Promise<boolean> {
    const enforcer = await this.casbinService.getEnforcer();
    const result = await enforcer.deleteRoleForUser(username, roleName);
    if (result) {
      await this.casbinService.reloadPolicy();
    }
    return result;
  }
  
  // 获取所有策略
  async getAllPolicies(): Promise<any[]> {
    const enforcer = await this.casbinService.getEnforcer();
    return await enforcer.getPolicy();
  }
  
  // 删除角色的所有权限
  async removeAllPermissionsFromRole(roleName: string): Promise<boolean> {
    const enforcer = await this.casbinService.getEnforcer();
    const policies = await enforcer.getPolicy();
    const rolePolicies = policies.filter(policy => policy[0] === roleName);
    
    let result = true;
    // 从数据库中删除所有角色策略
    for (const policy of rolePolicies) {
      const removed = await enforcer.removePolicy(policy[0], policy[1], policy[2]);
      if (removed) {
        await this.casbinService.removePolicyFromDatabase(policy[0], policy[1], policy[2]);
      } else {
        result = false;
      }
    }
    
    if (result) {
      await this.casbinService.reloadPolicy();
    }
    return result;
  }
  
  // 检查角色是否具有特定权限
  async checkRolePermission(roleName: string, resource: string, action: string): Promise<boolean> {
    const enforcer = await this.casbinService.getEnforcer();
    return await enforcer.enforce(roleName, resource, action);
  }
  
  // 获取角色的分类权限策略
  async getRoleCategoryPolicies(roleName: string): Promise<any[]> {
    // 强制重新加载策略以确保获取最新数据
    await this.casbinService.reloadPolicy();
    const enforcer = await this.casbinService.getEnforcer();
    // 获取所有策略并筛选出分类相关策略
    const policies = await enforcer.getPolicy();
    return policies.filter(policy => 
      policy[0] === roleName && 
      policy[1].startsWith('/category/') &&
      ['post', 'edit', 'review'].includes(policy[2])
    );
  }
  
  // 为角色分配分类权限
  async assignCategoryPermissionToRole(roleName: string, categoryId: number, action: string): Promise<boolean> {
    const enforcer = await this.casbinService.getEnforcer();
    const resource = `/category/${categoryId}`;
    const result = await enforcer.addPolicy(roleName, resource, action);
    if (result) {
      // 确保策略被持久化到数据库
      await this.casbinService.savePolicyToDatabase(roleName, resource, action);
      await this.casbinService.reloadPolicy();
    }
    return result;
  }
  
  // 删除角色的分类权限
  async removeCategoryPermissionFromRole(roleName: string, categoryId: number, action: string): Promise<boolean> {
    const enforcer = await this.casbinService.getEnforcer();
    const resource = `/category/${categoryId}`;
    const result = await enforcer.removePolicy(roleName, resource, action);
    if (result) {
      // 确保从数据库中删除策略
      await this.casbinService.removePolicyFromDatabase(roleName, resource, action);
      await this.casbinService.reloadPolicy();
    }
    return result;
  }
  
  // 删除角色的所有分类权限
  async removeAllCategoryPermissionsFromRole(roleName: string): Promise<boolean> {
    const enforcer = await this.casbinService.getEnforcer();
    const policies = await enforcer.getPolicy();
    const roleCategoryPolicies = policies.filter(policy => 
      policy[0] === roleName && 
      policy[1].startsWith('/category/') &&
      ['post', 'edit', 'review'].includes(policy[2])
    );
    
    let result = true;
    // 从数据库中删除所有角色分类策略
    for (const policy of roleCategoryPolicies) {
      const removed = await enforcer.removePolicy(policy[0], policy[1], policy[2]);
      if (removed) {
        await this.casbinService.removePolicyFromDatabase(policy[0], policy[1], policy[2]);
      } else {
        result = false;
      }
    }
    
    if (result) {
      await this.casbinService.reloadPolicy();
    }
    return result;
  }
  
  // 检查角色是否具有特定分类的特定权限
  async checkRoleCategoryPermission(roleName: string, categoryId: number, action: string): Promise<boolean> {
    const enforcer = await this.casbinService.getEnforcer();
    const resource = `/category/${categoryId}`;
    return await enforcer.enforce(roleName, resource, action);
  }
}